iT邦幫忙

2022 iThome 鐵人賽

DAY 30
3
Modern Web

強化 JavaScript 之 - 程式語感是可以磨練成就的系列 第 30

Day30-來看看 JavaScript 在 ES7~ES13 的幾個新特性

  • 分享至 

  • xImage
  •  

這篇會簡單粗淺的介紹幾個在 ES7~ES13 中我個人覺得比較重要和實用的特性。

ES7

Exponentiation Operator ** 指數運算子

**,可以做指數運算

console.log(Math.pow(2, 10)); // old

console.log(2 ** 10); // es7 new

ES8

Object.keys() & Object.values() & Object.entries()

Object.values()

取出物件內的 並組成陣列

Object.keys()

取出物件內的 屬性 並組成陣列

Object.entries()

取出物件內的 屬性屬性值 並組成陣列

String.prototype.padStart() & String.prototype.padEnd()

padStart() 會將用給定用於填充的字串,以重複的方式,插入到目標字串的起頭(左側),直到目標字串到達指定長度。

'abc'.padStart(10);         // "       abc"
'abc'.padStart(10, "foo");  // "foofoofabc"
'abc'.padStart(6,"123465"); // "123abc"

// -----------------

'Breaded Mushrooms'.padEnd(25, '.'); // "Breaded Mushrooms........"
'200'.padEnd(5); // "200  "

ES9

Promise.prototype.finally()

執行 Promise 後,不論是 resolved 或是 rejected,都會執行 finally() 函式。就像 try catch finally 那樣的關係。

let isLoading = true;

fetch(myRequest).then(function(response) {
    var contentType = response.headers.get("content-type");
    if(contentType && contentType.includes("application/json")) {
      return response.json();
    }
    throw new TypeError("Oops, we haven't got JSON!");
  })
  .then(function(json) { /* process your JSON further */ })
  .catch(function(error) { console.log(error); })
  .finally(function() { isLoading = false; });

ES10

Array.prototype.flat(depth)

就是做陣列扁平化的函式。

const a = [
  [1,2,3],[],['string'],[[1,2]],23,[444,22]
];

console.log(a.flat(Infinity)) // [1, 2, 3, 'string', 1, 2, 23, 444, 22]

Array.prototype.flatMap()

簡單說就是 map()+flat(1) 的函式。

const arr1 = [1, 2, 3, 4];

arr1.map(x => [x * 2]);
// [[2], [4], [6], [8]]

arr1.flatMap(x => [x * 2]);
// [2, 4, 6, 8]

arr1.flatMap(x => [[x * 2]]);
// [[2], [4], [6], [8]]

Map vs. flatMap

const friends = [
    {name: 'Dave', kids: ['Max', 'Jack']},
    {name: 'Max', kids: ['Sam', 'Alex', 'Megan']},
    {name: 'Jordan', kids: ['Mason', 'Cameron', 'Kaylin']}
];
const mapFunction = p => p.kids;
const names = friends.map(mapFunction);
console.log(names)

const mapFunction2 = p => p.kids;
const kidNames = friends.flatMap(mapFunction2);
console.log(kidNames);

catch 不再強制加上異常參數

可以省略 catch 回傳的參數 catch(err){} -> catch{}

如範例所示:

try {
  doSomethingThatMightThrow();
} catch { // → No binding or parameter!
  handleException();
}

ES11

Nullish Coalescing Operator 空值合併運算符 (?? 運算子)

當運算子的左手邊值為 null 或 undefined 的話,便會回傳右手邊值。

由於 || 運算符在判斷左邊的值時會强制轉型成 boolean 值,這會導致如果你使用 0,'' 或 NaN 作為有效值時會出現不可預料的後果,而 ?? 運算子成功地解決了此問題。

使用範例:

const name = null ?? 'harry';
console.log(name); // harry

const num = 0 ?? 42;
console.log(num); // 0

Optional Chaining Operator 可選串連運算子(?. 運算子)

?. 允許進行深層次的物件值存取,不用再寫程式碼判斷淺層物件是否存在。

const adventurer = {
  name: 'Alice',
  cat: {
    name: 'Dinah'
  }
};

const dogName = adventurer.dog?.name;
console.log(dogName);
// expected output: undefined

console.log(adventurer.someNonExistentMethod?.());
// expected output: undefined

Dynamic import()

這個版本的 JS 也能夠實現動態載入的功能:

button.addEventListener('click', () =>
  import('./module.mjs').then((module) => {
    module.myFunction();
  })
);
button.addEventListener('click', async () => {
  const { myFunction } = await import('./module.mjs');
  myFunction();
});

BigInt

一種新的資料型別,BigInt 提供了表示大於2^53的整數的功能 (2^53 是 JavaScript 原生的 Number 能夠表示的最大值)

globalThis

由於在不同的 JS 執行環境下去取得全域物件都需要不同的語法,而這個 globalThis 提供了統一的方式去取得個環境的全域物件,相當方便。

ES12

Logical AND assignment (&&=)

新的運算子,若 x &&= n,則 x 是 truthy 值時才會被賦予 n。

let a = 1;
let b = 0;

a &&= 2;
console.log(a); // 2

b &&= 2;
console.log(b); // 0

Logical OR assignment (||=)

&&= 相反,若 x &&= n,則 x 是 falsy 值時才會被賦予 n。

const a = { duration: 50, title: '' };

a.duration ||= 10;
console.log(a.duration); // 50

a.title ||= 'title is empty.';
console.log(a.title); // "title is empty"

Logical nullish assignment (??=)

x &&= n,則 x 是 nullish(null 或 undefined) 值時才會被賦予 n。

const person = { name: 'harry' };

person.name ??= 'Tom';
console.log(person.name); // harry

person.age ??= 24;
console.log(person.age); // 24

ES13

類別宣告屬性的方式的變更

以前的寫法是定義類別時,屬性需要在 constructor 內宣告,現在可以直接不用 constructor 就能宣告。

// old
class Animal {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

// new
class Animal {
  this.name = name;
  this.age = age;
}

可在全域使用 await

await 常搭配 async 使用,但現在可在全域時使用,不再強制包在 async 函式裡面。

function asyncTimeout(time) {
 return new Promise((resolve) => {
   setTimeout(() => {
     resolve('hi');
   }, time);
 });
}

await asyncTimeout(3000);

catch error 物件新增了屬性 - cause

如程式碼範例,這樣就可以註明導致這個錯誤訊息的原因。

  try {
    callApi();
  } catch (err) {
    throw new Error('error message', { cause: 'because ... so it leads to error.' });
  }

findLast() & findLastIndex()

用來查找陣列元素,不過是從陣列尾部開始查找。

const members = ['Jay', 'Mandy', 'Alice', 'Tom'];

const found = members.findLast((name) => name === 'Mandy');
const foundIndex = members.findLastIndex((name) => name === 'Mandy');

console.log(found); // Mandy
console.log(foundIndex); // 1

鐵人賽總結

讀者若要使用本篇提到的語法時可以再注意下瀏覽器兼容性,鐵人賽的系列文就到這篇結束,未來若還有跟 JS 有關並想分享給讀者的東西也會發在這個鐵人賽主題之類,所以務必訂閱一下接收通知囉~

希望讀完系列文的讀者都能有所收穫,也歡迎來交流討論一下文章提到的內容,另外雖然每篇文章我都花了不少時間整理和撰寫,但還是難保證不會完全沒有錯誤,所以若有看到不小心寫錯的地方非常歡迎跟我說!

各位明年再見囉~

參考資料 & 推薦閱讀

JS 語法 ES6、ES7、ES8、ES9、ES10、ES11、ES12 新特性


上一篇
Day29-寫出更好的 JavaScript 程式碼(下)
系列文
強化 JavaScript 之 - 程式語感是可以磨練成就的30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
1
json_liang
iT邦研究生 5 級 ‧ 2022-09-30 00:10:55

恭喜完賽/images/emoticon/emoticon08.gif

harry xie iT邦研究生 1 級 ‧ 2022-09-30 08:35:46 檢舉

謝謝~

1
hokou
iT邦好手 1 級 ‧ 2022-09-30 08:26:34

/images/emoticon/emoticon42.gif

恭喜完賽!

harry xie iT邦研究生 1 級 ‧ 2022-09-30 08:35:33 檢舉

感謝 hokou~

1
魚魚
iT邦新手 5 級 ‧ 2022-09-30 09:16:25

恭喜完賽!
這系列太讚了,非常詳細

harry xie iT邦研究生 1 級 ‧ 2022-09-30 09:30:42 檢舉

感謝支持!!

1
雷N
iT邦研究生 1 級 ‧ 2022-09-30 13:48:55

恭喜完賽了!!! /images/emoticon/emoticon08.gif
我會努力完賽的!!! 讓團隊一起邁過終點線!!!

十月找時間來喝茶跟大家聊天吧

harry xie iT邦研究生 1 級 ‧ 2022-09-30 15:16:09 檢舉

感謝~我相信我們團隊能順利完賽的/images/emoticon/emoticon12.gif

見面的話要看我康復了沒,最近剛好確診QQ

1
rocketpencil
iT邦新手 5 級 ‧ 2022-10-06 00:39:05

每篇都介紹得很清楚易懂,感謝大大參賽&恭喜完賽!!!

1
lagagain
iT邦新手 2 級 ‧ 2022-10-16 08:54:18

參考資料裡的內容竟然也沒有提到FinalizationRegistry。該說不愧是不知道該怎麼用的功能嗎XD?好多都忽略了喔~

恭喜完賽~~

harry xie iT邦研究生 1 級 ‧ 2022-10-16 09:40:45 檢舉

FinalizationRegistry 還真的沒聽過XD,太冷門就沒去注意了
來拜讀您的文章學習學習/images/emoticon/emoticon08.gif

謝謝~也恭喜您完賽

我要留言

立即登入留言